package com.clyz.material.service.es;

import com.clyz.material.dao.es.MaterialElasticRepository;
import com.clyz.material.entity.es.Material;
import org.apache.commons.lang.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import pl.touk.throwing.ThrowingFunction;

import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <h1></h1>
 *
 * @author Zemin.Yang
 */
@Service
public class MaterialElasticServiceImpl implements IMaterialElasticService {
    private final ElasticsearchRestTemplate elasticsearchTemplate;
    private final MaterialElasticRepository elasticRepository;

    private final Pageable pageable = PageRequest.of(0, 10);

    public MaterialElasticServiceImpl(ElasticsearchRestTemplate elasticsearchTemplate, MaterialElasticRepository elasticRepository) {
        this.elasticsearchTemplate = elasticsearchTemplate;
        this.elasticRepository = elasticRepository;
    }

    public void createIndex() {
        elasticsearchTemplate.createIndex(Material.class);
    }

    public void deleteIndex(String index) {
        elasticsearchTemplate.deleteIndex(index);
    }

    public void save(Material docBean) {
        elasticRepository.save(docBean);
    }

    public void saveAll(List<Material> list) {
        elasticRepository.saveAll(list);
    }

    public Iterator<Material> findAll() {
        return elasticRepository.findAll().iterator();
    }

    public Page<Material> findByContent(String content) {
        return elasticRepository.findByContent(content, pageable);
    }

    public Page<Material> search(String content, Integer type, int page, int size){
        if(StringUtils.isBlank(content)){
            return elasticRepository.findAll(PageRequest.of(page,size));
        }
        return elasticRepository.search(content,type,PageRequest.of(page, size));
    }

    @Override
    public void delete(String id) {
        elasticRepository.deleteById(id);
    }

    public Page<Material> query(String key) {
        return elasticRepository.findByContent(key, pageable);
    }

    @Transactional
    public List<Material> addOrUpdateBatch(List<Material> materials) {
        if (ObjectUtils.isEmpty(materials)) return null;
        return materials.stream().map(ThrowingFunction.unchecked(elasticRepository::save)).collect(Collectors.toList());
    }

    @Override
    public Material findById(String id) {
        return elasticRepository.findById(id).orElse(null);
    }
}
